package judesart.app.server;

import java.util.ArrayList;
import java.util.List;

import judesart.app.client.controller.GalleryController;
import judesart.app.domain.Artist;
import judesart.app.domain.Artwork;
import judesart.app.domain.Gallery;
import judesart.app.domain.Room;
import judesart.app.domain.RoomArtwork;
import judesart.app.domain.User;
import judesart.app.repository.ArtistDAO;
import judesart.app.repository.ArtworkDAO;
import judesart.app.repository.GalleryDAO;
import judesart.app.service.UserService;
import judesart.app.shared.SearchResult;
import judesart.app.shared.ValidationException;
import judesart.common.bean.ApplicationContextProvider;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class GalleryControllerImpl extends RemoteServiceServlet implements
        GalleryController {

    private static final long serialVersionUID = 1L;

    private final static Log LOGGER = LogFactory.getLog(GalleryControllerImpl.class);

    ArtistDAO artistDAO = ApplicationContextProvider.getCtx().getBean(
            ArtistDAO.class);
    UserService userService = ApplicationContextProvider.getCtx().getBean(
            UserService.class);
    ArtworkDAO artworkDAO = ApplicationContextProvider.getCtx().getBean(
            ArtworkDAO.class);
    GalleryDAO galleryDAO = ApplicationContextProvider.getCtx().getBean(
            GalleryDAO.class);

    @Override
    public Gallery createGallery(Gallery gallery) throws ValidationException {
        User user = userService.getCurrentUser();
        if (user != null) {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            gallery.setArtistId(artist.getId());
        }
        return galleryDAO.createGallery(gallery);
    }

    @Override
    public void deleteGallery(Long galleryId) {
        galleryDAO.deleteGallery(galleryId);
    }

    @Override
    public Gallery getGallery(Long id) {
        Gallery gallery = galleryDAO.findGalleryById(id);
        setTransientFields(gallery);
        return gallery;
    }

    @Override
    public SearchResult<Gallery> searchGalleries(int startAt, int maxElements) {
        Long artistId = getArtistId();
        int count = galleryDAO.countGalleries(artistId);
        List<Gallery> results = galleryDAO.findGalleries(artistId, startAt,
                maxElements);
        for (Gallery gallery : results) {
            setTransientFields(gallery);
        }
        LOGGER.debug(" > searchGalleries : " + results.size());
        return new SearchResult<Gallery>(new ArrayList<Gallery>(results), count);
    }

    private void setTransientFields(Gallery gallery) {
        if (gallery.getRooms() != null && gallery.getRooms().size() > 0) {
            for (Room room : gallery.getRooms()) {
                if (room.getArtworks() != null) {
                    for (int i = 0; i < room.getArtworks().size(); i++) {
                        setTransientFields(room.getArtworks().get(i));
                    }
                }
            }
        }
    }

    private void setTransientFields(RoomArtwork roomArtwork) {
        LOGGER.debug(" > setTransientFields [" + roomArtwork.getArtworkId()
                + "]");
        Artwork artwork = artworkDAO.findArtworkById(roomArtwork.getArtworkId());
        if (artwork.getPhotos() != null && artwork.getPhotos().size() > 0) {
            roomArtwork.setMainImageId(artwork.getPhotos().get(0).getImageId());
        }
        roomArtwork.setArtworkTitle(artwork.getTitle());
    }

    private Long getArtistId() {
        Long artistId;
        User user = userService.getCurrentUser();
        if (user != null) {
            Artist artist = artistDAO.findArtistByUserId(user.getId());
            if (artist != null)
                artistId = artist.getId();
            else
                artistId = null;
        } else {
            artistId = null;
        }
        return artistId;
    }

    @Override
    public Gallery updateGallery(Gallery gallery) throws ValidationException {
        return galleryDAO.updateGallery(gallery);
    }

    @Override
    public Room addRoomToGallery(Long galleryId, Room room) {
        Gallery gallery = galleryDAO.findGalleryById(galleryId);
        gallery = galleryDAO.addRoomToGallery(gallery, room);
        return gallery.getRooms().get(gallery.getRooms().size() - 1);
    }

    @Override
    public void updateRoom(Room room) {
        room = galleryDAO.updateRoom(room);
        LOGGER.debug(" < update room [" + room.getName() + "]");
    }

    @Override
    public void deleteRoom(Long galleryId, String roomId) {
        Gallery gallery = galleryDAO.findGalleryById(galleryId);
        galleryDAO.deleteRoomFromGallery(gallery, roomId);
    }

    @Override
    public Room getRoom(String roomKey) {
        Room room = galleryDAO.findRoomByKey(roomKey);
        setTransientFields(room.getGallery());
        return room;
    }

    @Override
    public void addArtworkToRoom(Long artworkId, String roomKey) {
        LOGGER.debug(" >> addArtworkToRoom [" + roomKey + "]");
        Room room = galleryDAO.findRoomByKey(roomKey);
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        galleryDAO.addArtworkToRoom(room, artwork);
    }

    @Override
    public void deleteArtworkFromRoom(Long artworkId, String roomKey) {
        Room room = galleryDAO.findRoomByKey(roomKey);
        Artwork artwork = artworkDAO.findArtworkById(artworkId);
        galleryDAO.deleteArtworkFromRoom(room, artwork);
    }

    @Override
    public List<Gallery> findAllUserGalleries(Long userId) {
        Artist artist = artistDAO.findArtistByUserId(userId);
        return new ArrayList<Gallery>(galleryDAO.findGalleries(artist.getId(),
                0, 100));
    }
}
